﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DARE
{
    public static class CExtentionMethod
    {
        private static readonly int[] DIVIDERPRIMITIVETYPE = new int[] { 3, 0, 2, 0 };

        public static bool Compare(this RasterizerState t, RasterizerState c)
        {
            if ((object)t != (object)c)
            {
                if ((object)t == null || (object)c == null)
                    return false;
            }
            else
                return true;
            return t.CullMode == c.CullMode
                && t.DepthBias == c.DepthBias
                && t.FillMode == c.FillMode
                && t.MultiSampleAntiAlias == c.MultiSampleAntiAlias
                && t.ScissorTestEnable == c.ScissorTestEnable
                && t.SlopeScaleDepthBias == c.SlopeScaleDepthBias;
        }

        public static void Draw(this ModelMeshPart t, GraphicsDevice m_device, PrimitiveType _type)
        {
            m_device.Indices = t.IndexBuffer;
            EffectTechnique _tech = t.Effect.CurrentTechnique;
            int _passCount = _tech.Passes.Count;
            for (int _index = 0; _index < _passCount; ++_index)
            {
                _tech.Passes[_index].Apply();
                m_device.DrawIndexedPrimitives(_type, t.VertexOffset, 0, t.NumVertices, t.StartIndex, t.PrimitiveCount);
            }
        }

        public static int IndexOf<TSource>(this IEnumerable<TSource> t, TSource item)
        {
            int index = 0;
            foreach (var elem in t)
            {
                if (elem.Equals(item))
                    return index;
                ++index;
            }
            return -1;
        }

        public static int IndexOfByValue<TSource, TValue>(this IEnumerable<TSource> t, TValue item)
            where TSource : IEquatable<TValue>
        {
            int index = 0;
            foreach (var elem in t)
            {
                if (elem.Equals(item))
                    return index;
                ++index;
            }
            return -1;
        }

        public static void Insert<TSource>(this List<TSource> t, TSource item, Predicate<TSource> pre)
        {
            for (int i = 0; i < t.Count; ++i)
            {
                if (pre(t[i]))
                {
                    t.Insert(i, item);
                    return;
                }
            }
            t.Add(item);
        }

        public static void InvokeTest(this BlendEvent t, IBlendController sender)
        {
            if (t != null)
                t.Invoke(sender);
        }

        public static bool Diff(this Matrix t, Matrix other)
        {
            return Diff(t, other, 3);
        }

        public static bool Diff(this Matrix t, Matrix other, int digit)
        {
            Matrix res = t - other;
            return Math.Round(res.M11, digit) != 0 && Math.Round(res.M12, digit) != 0 && Math.Round(res.M13, digit) != 0 && Math.Round(res.M14, digit) != 0 &&
                   Math.Round(res.M21, digit) != 0 && Math.Round(res.M22, digit) != 0 && Math.Round(res.M23, digit) != 0 && Math.Round(res.M24, digit) != 0 &&
                   Math.Round(res.M31, digit) != 0 && Math.Round(res.M32, digit) != 0 && Math.Round(res.M33, digit) != 0 && Math.Round(res.M34, digit) != 0 &&
                   Math.Round(res.M41, digit) != 0 && Math.Round(res.M42, digit) != 0 && Math.Round(res.M43, digit) != 0 && Math.Round(res.M44, digit) != 0;
        }
    }
}
